local skynet = require "skynet"
local Msger = require "core.Msger"
local PlayerConst = require "modules.player.PlayerConst"
require "skynet.manager"
local PlayerDB = require "modules.player.PlayerDB"
local bson = require "bson"
---@type PlayerMgr
local PlayerMgr = require"global.Services".PLAYER_MGR
local PlayerEvent = require "modules.player.PlayerEvent"

local M = {}

-- 玩家基础数据
local players = {}
local onlineCount = 0

function M.onlineCount()
    return onlineCount
end

local function defaultPlayer(playerId)
    return {
        _id = bson.objectid(),
        id = playerId,
        name = "p" .. playerId,
        coin = 1000,
        level = 1,
        exp = 0,
        vip = 0
    }
end

local function getLoginData(playerId)
    local player = players[playerId]
    if not player then
        return
    end

    return {
        id = player.id,
        name = player.name,
        coin = player.coin,
        level = player.level,
        exp = player.exp,
        vip = player.vip
    }
end

local function getPlayerInfo(playerId, keys)
    local player = players[playerId]
    if player then
        if keys then
            local result = {}
            for k, v in pairs(keys) do
                if v ~= 0 then
                    result[k] = player[k]
                end
            end

            return result
        end

        return player
    end

    return PlayerDB.getPlayer(playerId, keys)
end

---@param keys table<string, number> 对应 mongodb 中的 projection
function M.getPlayerInfo(playerId, keys)
    return getPlayerInfo(playerId, keys)
end

-- 演示登录
function M.login(playerId)
    -- 如果玩家不存在，否则创建新账号
    local player = PlayerDB.getPlayer(playerId)
    if not player then
        player = defaultPlayer(playerId)
        PlayerDB.createPlayer(player)
    end

    players[playerId] = player
    onlineCount = onlineCount + 1
    return getLoginData(playerId)
end

function M.isCoinEnough(playerId, coin)
    local player = getPlayerInfo()
    if not player then
        return false
    end

    return player.coin >= coin
end

function M.incrementCoin(playerId, coin)
    local player = getPlayerInfo(playerId, {
        coin = 1,
        _id = 0
    })

    local endCoin = player.coin + coin
    if endCoin > PlayerConst.MAX_COIN_NUM then
        coin = PlayerConst.MAX_COIN_NUM - player.coin
        Msger.send(playerId, PlayerEvent.PLAYER_COIN_OVERFLOW)
    end

    player.coin = player.coin + coin
    PlayerDB.incrementCoin(playerId, coin)
end

function M.decrementCoin(playerId, coin)
    local player = getPlayerInfo(playerId, {
        coin = 1,
        _id = 0
    })

    if coin > player.coin then
        return false
    end

    player.coin = player.coin - coin
    PlayerDB.decrementCoin(playerId, coin)
    return true
end

function M.onLogout(playerId)
    onlineCount = onlineCount - 1
    players[playerId] = nil
end

function M.isPlayerExist(playerId)
    if players[playerId] then
        return true
    end

    return PlayerDB.isPlayerExist(playerId)
end

-- 启动函数
function M.start()
    -- 所有游戏模块init之后调用
end

M.listeners = {
    [PlayerEvent.PLAYER_LOGOUT] = M.onLogout
}

function M.init()
    skynet.dispatch_lua_queue(M)
end

return M
